<?php
namespace Home\Controller;
use Think\Controller;

class PaycommonController extends CommonController {
    protected $alipay_config = null;//支付宝配置信息

    protected $auth_status = 0;//默认：未认证
    protected $user_email = null;//用户邮箱
    protected $uid = null;
    protected $user_token = null;
    protected $auth_type = 1;
    protected $user_tel = null;

    public function __construct(){
        parent::__construct();
        //是否普通用户，且是登录状态
        
        $this->getAuthStatus();
        $this->auth_status = session('37degree_auth_status');
        
        $this->user_email = session('user_email');
        $this->assign('user_email',$this->user_email);
        $this->uid = session('uid');
        $this->user_token = session('user_token');
        $this->auth_type = session('auth_type');
        $this->user_tel = session('user_tel');

        $this->assign('user_token',$this->user_token);
        
        // 用户信息
        if($this->role != -1){// 游客
            $this->user_email = session('user_email');
            $this->assign('user_email',$this->user_email);
        }
        $this->assign('role',$this->role);

        $this->alipay_config = array(
            //合作身份者ID，签约帐号，以2088开头由16位纯数字组成的字符串，查看地址：https://openhome.alipay.com/platform/keyManage.htm?keyType=partner
            'partner'=>C('PARTNER'),
            //收款支付宝帐号，以2088开头由16位纯数字组成的字符串，一般情况下收款帐号就是签约帐号
            'seller_id'=>C('SELLER_ID'),
            //商户的私钥,此处填写原始私钥去头去尾，RSA公私钥生成：https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.nBDxfy&treeId=58&articleId=103242&docType=1
            'private_key'=>trim(C('PRIVATE_KEY')),

            //支付宝的公钥，查看地址：https://b.alipay.com/order/pidAndKey.htm
            'alipay_public_key'=>trim(C('ALIPAY_PUBLIC_KEY')),
            // 服务器异步通知页面路径  需http://格式的完整路径，不能加?id=123这类自定义参数，必须外网可以正常访问
            'notify_url'=>C('NOTIFY_URL'),
            // 页面跳转同步通知页面路径 需http://格式的完整路径，不能加?id=123这类自定义参数，必须外网可以正常访问
            'return_url'=>C('RETURN_URL'),
            //签名方式
            'sign_type'=> strtoupper( C('SIGN_TYPE') ),
            //字符编码格式 目前支持 gbk 或 utf-8
            'input_charset'=>trim(strtolower(C('INPUT_CHARSET'))),
            //ca证书路径地址，用于curl中ssl校验
            //请保证cacert.pem文件在当前文件夹目录中
            'cacert'=>getcwd().'\\cert\\alipaykey\\cacert.pem',
            //访问模式,根据自己的服务器是否支持ssl访问，若支持请选择https；若不支持请选择http
            'transport'=>C('TRANSPORT'),
            // 支付类型 ，无需修改
            'payment_type'=>C('PAYMENT_TYPE'),
            // 产品类型，无需修改
            'service'=>C('SERVICE'),
            // 防钓鱼时间戳  若要使用请调用类文件submit中的query_timestamp函数
            'anti_phishing_key'=>C('ANTI_PHISHING_KEY'),
            // 客户端的IP地址 非局域网的外网IP地址，如：221.0.0.1
            'exter_invoke_ip'=>C('EXTER_INVOKE_IP')
        );
        $this->assign('head_title',"支付－云途数据市场");
    }

    //校验是否登录，认证，是否服务商帐号
    protected function checkBuyUser($isAjax = false){
        $return = true;
        $msg = 'OK';
        $status = 200;

        if(empty($this->uid)){
            $return = false;
            $msg = "请登录";
            $status = 4001;
        }else if($this->auth_status!=2){
            $return = false;
            $msg = "请认证";
            $status = 4002;
        }
        //去掉购买限制，服务商用户也可以购买
        // if($this->role==2){
        //     $return = false;
        //     $msg = "请登录普通用户帐号购买";
        //     $status = 4003;
        // }

        if($return != true){
            if($isAjax){
                $this->ajaxReturn( array('status'=>$status,'msg'=>$msg,'data'=>null));
            }
        }else{
            return array('status'=>$status,'msg'=>$msg,'data'=>null);
        }

    }

// 报告及API购买公用---start
    //异步通知---报告及API购买公用
    public function alipay_notify(){
        header("Content-type:text/html;charset=utf-8");
        $data = I('post.');
        //支付宝验签
        Vendor('Pay.alipay.alipay_notify','','.class.php');
        $alipayNotify = new \AlipayNotify($this->alipay_config);
        $verify_result = $alipayNotify->verifyNotify();

        //判断支付状态，是否成功
        if($verify_result){
            if($data['trade_status']=='TRADE_SUCCESS'){
                //支付宝回调记录
                $pay_fail_destination = C('LOG_PATH').'alipay_notify/'.date('y_m_d').'.log';
                $pay_fail_message = "支付宝回调-验签成功记录:".$data['out_trade_no']."--支付宝交易编号：".$data['trade_no']."-金额:".$data['total_fee']."元人民币-"."-购买用户邮箱:".$data['buyer_email']."-商品信息:".$data['body']."---回调信息:".json_encode($data);
                \Think\Log::write($pay_fail_message,'INFO',$type='',$pay_fail_destination);

                $all_body = explode("-",$data['extra_common_param']);
                $pay_type = $all_body[2];

                if($pay_type==2){
                    $orderModel = M('ReportOrders');
                }else{
                    $orderModel = M('Orders');
                }
                $order_info = $orderModel->where("order_id='".$data['out_trade_no']."'")->find();
                if(!empty($order_info) && ( $order_info['pay_status']==0 || $order_info['pay_status']==-1) ){
                    //更新订单状态
                    try{
                        //入库//更新订单状态
                        if($pay_type==1){//API
                            $result = $this->alipay_success_update_table_for_api($data);
                        }else if($pay_type==2){//报告
                            $result = $this->alipay_success_update_table_for_report($data);
                        }else{
                            $result = false;
                        }

                    }catch(exception $e){
                       \Think\Log::write("exception",'INFO',$type='',C('LOG_PATH').'test/'.date('y_m_d').'.log'); 
                    }
                }
                echo "success";DIE;
            }else{
                //订单支付失败

                //日志
                $pay_fail_destination = C('LOG_PATH').'alipay_notify/'.date('y_m_d').'.log';
                $pay_fail_message = "支付宝回调-验签成功-支付失败记录:".$data['out_trade_no']."--支付宝交易编号：".$data['trade_no']."-金额:".$data['total_fee']."元人民币-"."-购买用户邮箱:".$data['buyer_email']."-商品信息:".$data['body']."---回调信息:".json_encode($data);
                \Think\Log::write($pay_fail_message,'INFO',$type='',$pay_fail_destination);

                ECHO "fail";DIE;
            }
            
        }else{
            //订单支付失败

            //日志
            $pay_fail_destination = C('LOG_PATH').'alipay_notify/'.date('y_m_d').'.log';
            $pay_fail_message = "支付宝回调-验签失败记录:".$data['out_trade_no']."--支付宝交易编号：".$data['trade_no']."-金额:".$data['total_fee']."元人民币-"."-购买用户邮箱:".$data['buyer_email']."-商品信息:".$data['body']."---回调信息:".json_encode($data);
            \Think\Log::write($pay_fail_message,'INFO',$type='',$pay_fail_destination);

            ECHO "fail";DIE;
        }

    }

    //alipay返回直接结果---报告及API购买公用
    public function alipay_return(){
        header("Content-type:text/html;charset=utf-8");
        $data = I('get.');
        
        //支付宝校验
        Vendor('Pay.alipay.alipay_notify','','.class.php');

        $alipayNotify = new \AlipayNotify($this->alipay_config);
        $verify_result = $alipayNotify->verifyReturn();

        // $this->alipay_success_update_table($data);die;
        //验签---判断支付状态，是否成功
        if($verify_result){
            if($data['trade_status']=='TRADE_SUCCESS'){
                $all_body = explode("-",$data['extra_common_param']);
                $pay_type = $all_body[2];

                if($pay_type==2){
                    $orderModel = M('ReportOrders');
                }else{
                    $orderModel = M('Orders');
                }
                $order_info = $orderModel->where("order_id='".$data['out_trade_no']."'")->find();
                if(!empty($order_info) && ( $order_info['pay_status']==0 || $order_info['pay_status']==-1) ){
                    //入库//更新订单状态
                    if($pay_type==1){//API
                        $result = $this->alipay_success_update_table_for_api($data);
                    }else if($pay_type==2){//报告
                        $result = $this->alipay_success_update_table_for_report($data);
                    }else{
                        $result = false;
                    } 
                }
                
                $this->assign('amount',$data['total_fee']);
                $this->display('success');
            }else{
                //订单支付失败

                //日志
                $pay_fail_destination = C('LOG_PATH').'pay_fail/'.date('y_m_d').'.log';
                $pay_fail_message = "付款失败-订单编号:".$order_id."-金额:".$data['total_fee']."元人民币-"."-用户邮箱:".$user_email."-用户uid:".$user_id."-服务编号:".$service_id."-API编号:".$api_id."-套餐名称:".$package_name."-返回信息：".json_encode($data);
                \Think\Log::write($pay_fail_message,'INFO',$type='',$pay_fail_destination);

                $this->display('fail');
                // $this->error('支付失败','/');
            }
            

        }else{
            //订单支付失败

            //日志
            $pay_fail_destination = C('LOG_PATH').'pay_fail/'.date('y_m_d').'.log';
            $pay_fail_message = "验签失败-订单编号:".$order_id."-金额:".$data['total_fee']."元人民币-"."-用户邮箱:".$user_email."-用户uid:".$user_id."-服务编号:".$service_id."-API编号:".$api_id."-套餐名称:".$package_name."-返回信息：".json_encode($data);
            \Think\Log::write($pay_fail_message,'INFO',$type='',$pay_fail_destination);

            $this->display('fail');
            // $this->error('支付失败','/');
        }

    }    

    //wxpay回调url---报告及API购买公用
    public function wxpay_notify(){
        ini_set('date.timezone','Asia/Shanghai');
        Vendor('Pay.wxpay.WxPay#Api','','.php');
        Vendor('Pay.wxpay.WxPay#Notify','','.php');

        $notify = new \WxPayNotify();
        $needSign = false;
        $result = $notify->Handle($needSign);

        $wxpay_destination = C('LOG_PATH').'wxpay_notify/'.date('y_m_d').'.log';
        $xml = file_get_contents("php://input"); 

        if($result){//验签成功
            // $xml = $GLOBALS['HTTP_RAW_POST_DATA'];
            $xml_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
            $xml_data['extra_common_param'] = $xml_data['attach'];
            $xml_data['notify_time'] = $xml_data['time_end'];
            $xml_data['total_fee'] = round($xml_data['total_fee']/100,2);//微信支付最小单位是“分”

            $all_body = explode("-",$xml_data['attach']);
            $pay_type = $all_body[2];
            //入库
            if($pay_type==1){//API
                $result = $this->alipay_success_update_table_for_api($xml_data);
            }else if($pay_type==2){//报告
                $result = $this->alipay_success_update_table_for_report($xml_data);
            }else{
                $result = false;
            }
            
            if($result) {
                $notify->ReplyNotify($needSign);//稍后去掉注释
                
                $pay_ok_message = "wx_pay:ok-";
                $pay_ok_message .= json_encode($xml_data);
                
                \Think\Log::write($pay_ok_message,'INFO',$type='',$wxpay_destination);
            }else{
                $pay_ok_message = "wx_pay:insert into table fail-";
                $pay_ok_message .= json_encode($xml_data);

                \Think\Log::write($pay_ok_message,'INFO',$type='',$wxpay_destination);
            }

        }else{
            $pay_ok_message = "wx_pay:wx_fail-";
            $xml_data_new = $notify->FromXml($xml);
            $pay_ok_message .= json_encode($xml_data_new);

            \Think\Log::write($pay_ok_message,'INFO',$type='',$wxpay_destination);
        }
    }

// 报告及API购买公用---end

    //更新库记录-API购买更新记录
    private function alipay_success_update_table_for_api($data){
        //获取订单信息：订单编号，根据订单编号查询订单信息
        $order_id = $data['out_trade_no'];
        // $all_body = explode("-", $data['body']);
        $all_body = explode("-",$data['extra_common_param']);

        //商品描述，可空---format--邮箱-购买者用户id-购买产品类型（1：API；2：报告）
        $user_email = $all_body[0];
        $user_id = $all_body[1];
        $pay_type = $all_body[2];
        
        $orderModel = M('Orders');
        $order_info = $orderModel->where("order_id='".$order_id."'")->find();

        //下单失败，付款成功时---记录日志，短信通知
        if(empty($order_info)){
            //日志
            $faild_order_destination = C('LOG_PATH').'faild_order_db/'.date('y_m_d').'.log';
            $order_faild_message = "订单库查找该订单失败,付款成功-订单编号:".$order_id."-金额:".$data['total_fee']."元人民币-"."-用户邮箱:".$user_email."-用户uid:".$user_id."-服务编号:".$order_info['service_id']."-API编号:".$order_info['api_id']."-套餐名称:".$order_info['package_name']."--导致更新订单及账户金额，请求网关没有处理";

            \Think\Log::write($order_faild_message,'ERR',$type='',$faild_order_destination);

            return false;
        }

        //请求网关
        $gateway_params['service'] = $order_info['service_name_en'];
        $gateway_params['api'] = $order_info['api_name_en'];
        $gateway_params['user'] = $user_email;
        $gateway_params['cnt_limit'] = 1;//访问频率限制
        $gateway_params['rate_limit'] = 1;//访问次数限制

        // expire_time     int     否   访问过期时间 unixtime -1为永远不过期 默认为-1
        //获取最后一次付款成功过期时间-开始时间 + 天数
        $orderModel = D('Order');
        $surplus_time = $orderModel->getSuccessOrderTime($user_id,$order_info['api_id']);

        $condition_json = json_decode($order_info['condition_json'],true);
        $day = 31;//周期
        isset($condition_json['package_date'])?($day=$condition_json['package_date']):($day = 31);
        $expire_time = $day * 24 * 3600; 

        $gateway_params['expire_time'] = time() + $expire_time + $surplus_time;
        //频次时间限制-请求网关
        //查询用户购买记录（已经成功付款）
        $order_api_verify = $orderModel->verifyApiWithUid($user_id,$order_info['service_id'],$order_info['api_id']);
        if($order_api_verify!==false){
            if($order_api_verify==0){//没有购买记录
                $gateway_result = $this->gatewayAuthadd($gateway_params);
                $gateway_authadd_destination = C('LOG_PATH').'gateway_auth_add/'.date('y_m_d').'.log';
                \Think\Log::write(json_encode($gateway_result),'INFO',$type='',$gateway_authadd_destination);

                //请求条数限制-请求网关
                $gateway_order['service'] = $order_info['service_name_en'];
                $gateway_order['api'] = $order_info['api_name_en'];
                $gateway_order['user'] = $user_email;
                $gateway_order['cnt'] = $order_info['limit_num'];
                $gateway_order_result = $this->gatewayOrdervary($gateway_order);
                $gateway_order_destination = C('LOG_PATH').'gateway_order/'.date('y_m_d').'.log';
                \Think\Log::write(json_encode($gateway_order_result),'INFO',$type='',$gateway_order_destination);
            }else{
                $gateway_result = $this->gatewayAuthupdate($gateway_params);
                $gateway_authadd_destination = C('LOG_PATH').'gateway_auth_add/'.date('y_m_d').'.log';
                \Think\Log::write(json_encode($gateway_result),'INFO',$type='',$gateway_authadd_destination);

                //请求条数限制-请求网关
                $gateway_order['service'] = $order_info['service_name_en'];
                $gateway_order['api'] = $order_info['api_name_en'];
                $gateway_order['user'] = $user_email;
                $gateway_order['cnt'] = $order_info['limit_num'];

                //购买产品是否过期---todo
                if($surplus_time===0){//有购买，但购买产品过期
                    $gateway_order_result = $this->gatewayOrderSet($gateway_order);//todo
                }else{
                    $gateway_order_result = $this->gatewayOrdervary($gateway_order);  
                }

                $gateway_order_destination = C('LOG_PATH').'gateway_order/'.date('y_m_d').'.log';
                \Think\Log::write(json_encode($gateway_order_result),'INFO',$type='',$gateway_order_destination);
            }
        }else{
            return false;
        }
        
        //开启事务
        $orderModel->startTrans();
        //改写订单状态，流水记录表，服务商帐号收款
        $pay_time = strtotime($data['notify_time']);
        $order_data = array('pay_status'=>1,"pay_time"=>$pay_time,"begin_time"=>$pay_time,'expire_time'=>$gateway_params['expire_time'],'pay_status'=>1,'enable'=>1,'pay_platform_name'=>$data['buyer_email'],'expire_time'=>$gateway_params['expire_time']);
        $update_order_status = $orderModel->where("order_id='".$order_id."'")->save($order_data);

        $payhistoryModel = M('PaymentsHistory');
        $pay_history_data = array('from_uid'=>$order_info['user_id'],'from_username'=>$order_info['user_name'],'to_uid'=>$order_info['works_uid'],'amount'=>$data['total_fee'],'payments_type'=>1,'create_time'=>time(),'payments_reason'=>'购买：'.$order_info['api_name']."  ",'order_id'=>$order_id);
        $add_pay_history = $payhistoryModel->data($pay_history_data)->add();

        $uservaultModel = M('UserVault');
        //先查询是否有该用户记录
        $uservault_count = $uservaultModel->where('uid='.$order_info['works_uid'])->count();//->lock(true)
        if($uservault_count){
           $uservault_result = $uservaultModel->where('uid='.$order_info['works_uid'])->setInc("amount",$data['total_fee']);

        }else{
            $user_vault_data = array('uid'=>$order_info['works_uid'],'user_name'=>'test','amount'=>$data['total_fee']);
            $uservault_result = $uservaultModel->data($user_vault_data)->add();
        }
        
        //购买服务，新增购买数量-modify 20161024 start
        $serviceModel = M('Services');
        $serviceModel->where("service_id=".$order_info['service_id'])->setInc('call_num');
        //购买服务，新增购买数量-modify 20161024 end

        if ($uservault_result && $add_pay_history && $update_order_status){
            // 提交事务
            $orderModel->commit();

            //成功
            $pay_success_destination = C('LOG_PATH').'pay_success/'.date('y_m_d').'.log';
            $pay_success_message = "付款及状态更新成功-订单编号:".$order_id."-金额:".$data['total_fee']."元人民币-"."-用户邮箱:".$user_email."-用户uid:".$user_id."-服务编号:".$order_info['service_id']."-API编号:".$order_info['api_id']."-套餐名称:".$order_info['package_name'];
            \Think\Log::write($pay_success_message,'INFO',$type='',$pay_success_destination);
            return true;
        }else{
            //日志记录，短信通知
            $pay_updatesql_fail_destination = C('LOG_PATH').'paysucces_updatesql_fail/'.date('y_m_d').'.log';
            $pay_updatesql_fail_message = "付款成功,更新订单及账户金额失败-订单编号:".$order_id."-金额:".$data['total_fee']."元人民币-"."-用户邮箱:".$user_email."-用户uid:".$user_id."-服务编号:".$order_info['service_id']."-API编号:".$order_info['api_id']."-套餐名称:".$order_info['package_name'];
            \Think\Log::write($pay_updatesql_fail_message,'INFO',$type='',$pay_updatesql_fail_destination);

           // 事务回滚
           $orderModel->rollback();

           return false;
        }
    }

    //更新库记录---报告购买记录
    private function alipay_success_update_table_for_report($data){
        //获取订单信息：订单编号，根据订单编号查询订单信息
        $order_id = $data['out_trade_no'];
        $all_body = explode("-",$data['extra_common_param']);

        //商品描述，可空---format--邮箱-购买者用户id-购买产品类型（1：API；2：报告）
        $user_email = $all_body[0];
        $user_id = $all_body[1];
        $pay_type = $all_body[2]; 
        
        $orderModel = M('ReportOrders');
        $order_info = $orderModel->where("order_id='".$order_id."'")->find();

        //下单失败，付款成功时---记录日志，短信通知
        if(empty($order_info)){
            //日志
            $faild_order_destination = C('LOG_PATH').'faild_order_db/'.date('y_m_d').'.log';
            $order_faild_message = "订单库查找该订单失败,付款成功-订单编号:".$order_id."-金额:".$data['total_fee']."元人民币-"."-用户邮箱:".$user_email."-用户uid:".$user_id."-报告编号:".$order_info['report_id']."--导致更新订单及账户金额，请求网关没有处理";

            \Think\Log::write($order_faild_message,'ERR',$type='',$faild_order_destination);

            return false;
        }

        //开启事务
        $orderModel->startTrans();
        //改写订单状态，流水记录表，服务商帐号收款
        $pay_time = strtotime($data['notify_time']);
        $order_data = array('pay_status'=>1,"pay_time"=>$pay_time,'pay_platform_username'=>$data['buyer_email']);
        $update_order_status = $orderModel->where("order_id='".$order_id."'")->save($order_data);

        $payhistoryModel = M('PaymentsHistory');
        $pay_history_data = array('from_uid'=>$order_info['uid'],'from_username'=>$order_info['user_name'],'to_uid'=>$order_info['works_uid'],'amount'=>$data['total_fee'],'payments_type'=>1,'create_time'=>time(),'payments_reason'=>'购买-报告：'.$order_info['report_title']."  ",'order_id'=>$order_id);
        $add_pay_history = $payhistoryModel->data($pay_history_data)->add();

        $uservaultModel = M('UserVault');
        //先查询是否有该用户记录
        $uservault_count = $uservaultModel->where('uid='.$order_info['works_uid'])->count();//->lock(true)
        if($uservault_count){
           $uservault_result = $uservaultModel->where('uid='.$order_info['works_uid'])->setInc("amount",$data['total_fee']);

        }else{
            $user_vault_data = array('uid'=>$order_info['works_uid'],'user_name'=>'test','amount'=>$data['total_fee']);
            $uservault_result = $uservaultModel->data($user_vault_data)->add();
        }
        
        //购买报告，新增购买数量-modify 20161024 start
        // $reportModel = M('Report');
        // $reportModel->where("id=".$order_info['report_id'])->setInc('use_nums');
        //购买报告，新增购买数量-modify 20161024 end

        if ($uservault_result && $add_pay_history && $update_order_status){
            // 提交事务
            $orderModel->commit();

            //成功
            $pay_success_destination = C('LOG_PATH').'pay_success/'.date('y_m_d').'.log';
            $pay_success_message = "付款及状态更新成功-订单编号:".$order_id."-金额:".$data['total_fee']."元人民币-"."-用户邮箱:".$user_email."-用户uid:".$user_id."-报告编号:".$order_info['report_id'];
            \Think\Log::write($pay_success_message,'INFO',$type='',$pay_success_destination);
            return true;
        }else{
            //日志记录，短信通知
            $pay_updatesql_fail_destination = C('LOG_PATH').'paysucces_updatesql_fail/'.date('y_m_d').'.log';
            $pay_updatesql_fail_message = "付款成功,更新订单及账户金额失败-订单编号:".$order_id."-金额:".$data['total_fee']."元人民币-"."-用户邮箱:".$user_email."-用户uid:".$user_id."-服务编号:".$order_info['report_id'];
            \Think\Log::write($pay_updatesql_fail_message,'INFO',$type='',$pay_updatesql_fail_destination);

           // 事务回滚
           $orderModel->rollback();

           return false;
        }
    }

}